package com.zhoug.permission2;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.preference.PreferenceManager;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;
import java.util.Random;
import java.util.UUID;

/**
 * @Author 35574
 * @Date 2021/6/7
 * @Description
 */
public class ZPermissions {
    private static final String TAG = ">>>ZPermissions";
    private static boolean debug = false;


    private Context mContext;
    /**
     * 权限申请回掉
     */
    private Callback mCallback;
    /**
     * 需要申请的权限集合
     */
    private String[] permissions;
    /**
     * 需要请求权限集合,在{@link #permissions}中去掉已经授权的权限后剩下的需要用户授权的
     */
    private ArrayList<String> shouldRequestPermissions;
    /**
     * 权限使用目的描述,为null是显示默认描述
     */
    private String description = null;
    /**
     * 是否在权限申请之前显示权限描述窗口
     */
    private boolean showDescription = true;
    /**
     * 用户拒绝权限后间隔多长时间才能再次请求权限,单位毫秒
     */
    private long intervalTime = 0;
    /**
     * 存储上次请求权限的可以
     */
    private String lastRequestKey = null;

    /**

    /**
     * 是否显示noAsking窗口提示
     */
    private boolean showNoAsking = true;

    /**
     * 权限申请广播
     */
    private RequestPermissionBroadcastReceiver mReceiver;

    /**
     * 权限申请描述窗口
     */
    private static IPermissionDescriptionDialog permissionDescriptionDialog;
    /**
     * 用户勾选了不在提示后缺失权限提醒窗口
     */
    private static INotAskingPermissionDialog notAskingPermissionDialog;


    public static ZPermissions with(Context context) {
        return new ZPermissions(context);
    }


    private ZPermissions(Context context) {
        this.mContext = context;
    }

    /**
     * 检查全部权限是否已经授权
     *
     * @return
     */
    public boolean check() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //没有添加权限
            if (permissions == null || permissions.length == 0) {
                return true;
            } else {
                for (String permission : permissions) {
                    if (ActivityCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * 开始权限请求
     */
    public void request() {
        //重置需要请求的权限
        shouldRequestPermissions = null;
        //没有权限需要申请
        if (permissions == null || permissions.length == 0) {
            if (mCallback != null) {
                mCallback.onRequestPermissionsResult(true, null, null);
            }
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            shouldRequestPermissions();
            if (shouldRequestPermissions == null || shouldRequestPermissions.size() == 0) {
                if (debug) {
                    Log.d(TAG, "全部权限已授权");
                }
                if (mCallback != null) {
                    mCallback.onRequestPermissionsResult(true, null, null);
                }
            } else {
                //需要请求权限
                if (debug) {
                    Log.d(TAG, String.format(Locale.CANADA, "需要请求的权限(%d):%s", shouldRequestPermissions.size(), shouldRequestPermissions.toString()));
                }
                if (!_isOverIntervalRequestTime()) {
                    if (mCallback != null) {
                        mCallback.onRequestPermissionsResult(false, null, shouldRequestPermissions);
                    }
                    return;
                }
                startPermissionActivity();
            }
        } else {
            //6.0以下版本
            if (mCallback != null) {
                mCallback.onRequestPermissionsResult(true, null, null);
            }
        }

    }

    /**
     * 筛选出需要用户授权的权限
     */
    private void shouldRequestPermissions() {
        if (permissions == null || permissions.length == 0) {
            return;
        }
        //没有的权限加入集合
        shouldRequestPermissions = new ArrayList<>();
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) {
                shouldRequestPermissions.add(permission);
            }
        }

    }


    /**
     * 启动权限申请页面
     */
    private void startPermissionActivity() {
        //注册广播
        Log.i(TAG, "startPermissionActivity: 注册广播");
        mReceiver = new RequestPermissionBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        String action = UUID.randomUUID().toString();
        filter.addAction(action);
        mContext.registerReceiver(mReceiver, filter);

        int requestCode = new Random().nextInt(1000);

        Intent intent = new Intent(mContext, PermissionsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putStringArrayListExtra("permissions", shouldRequestPermissions);
        intent.putExtra("showNoAsking", showNoAsking);
        intent.putExtra("requestCode", requestCode);
        intent.putExtra("action", action);
        intent.putExtra("showDescription", showDescription);
        intent.putExtra("description", description);
        mContext.startActivity(intent);

    }


    //自定义广播接受权限申请结果
    private class RequestPermissionBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
                boolean success = intent.getBooleanExtra("success", false);
                ArrayList<String> granted = intent.getStringArrayListExtra("granted");
                ArrayList<String> denied = intent.getStringArrayListExtra("denied");
                if(!success){
                    keepLastTime(denied);
                }
                mCallback.onRequestPermissionsResult(success, granted, denied);
            } else {
                mCallback.onRequestPermissionsResult(false, null, shouldRequestPermissions);
            }

            unregisterReceiver();
        }
    }

    private SharedPreferences _getSP() {
        return PreferenceManager.getDefaultSharedPreferences(mContext);
    }

    /**
     * 如果{@link #lastRequestKey}为kong,则使用未申请成功的权限来生成key
     *
     * @param permission
     * @return
     */
    private String _getLastRequestKey(ArrayList<String> permission) {
        String key = null;
        if (lastRequestKey != null && lastRequestKey.length() > 0) {
            key = MUtils.getMD5(lastRequestKey);
        } else if (permission != null && permission.size() > 0) {
            //排序
            Collections.sort(permission);
            int length = permission.size() - 1;
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i <= length; i++) {
                builder.append(permission.get(i));
                if (i < length) {
                    builder.append(",");
                }
            }
            key = MUtils.getMD5(builder.toString()).toUpperCase();
        }
        if (debug) {
            Log.d(TAG, "_getLastRequestKey:" + key);
        }
        return key;
    }

    /**
     * 超过间隔时间可以请求权限了
     *
     * @return
     */
    private boolean _isOverIntervalRequestTime() {
        //权限申请间隔时间
        if (intervalTime > 0) {
            String key = _getLastRequestKey(shouldRequestPermissions);
            if (key != null) {
                long time = System.currentTimeMillis();
                long lastTime = _getSP().getLong(key, 0);
                long interval = time - lastTime;
                if (debug) {
                    Log.d(TAG, "interval:" + interval);
                }
                if (interval < intervalTime) {
                    if (debug) {
                        Log.d(TAG, "request:权限间隔时间还不够");
                    }
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 保存拒绝权限的时间
     */
    private void keepLastTime(ArrayList<String> permission) {
        String s = _getLastRequestKey(permission);
        if (s != null) {
            if (debug) {
                Log.d(TAG, "keepLastTime:保存拒绝权限的时间");
            }
            SharedPreferences.Editor edit = _getSP().edit();
            edit.putLong(s, System.currentTimeMillis());
            edit.apply();
        }
    }


    public static void setDebug(boolean debug) {
        ZPermissions.debug = debug;
    }

    public static boolean isDebug() {
        return ZPermissions.debug;
    }

    /**
     * 权限申请描述窗口
     * @param permissionDescriptionDialog
     */
    public static void setPermissionDescriptionDialog(IPermissionDescriptionDialog permissionDescriptionDialog) {
        ZPermissions.permissionDescriptionDialog = permissionDescriptionDialog;
    }

    public static IPermissionDescriptionDialog getPermissionDescriptionDialog() {
        if(permissionDescriptionDialog==null){
            permissionDescriptionDialog=new PermissionDescriptionDialog();
        }
        return permissionDescriptionDialog;
    }

    /**
     * 用户勾选了不在提示后缺失权限提醒窗口
     * @param notAskingPermissionDialog
     */
    public static void setNotAskingPermissionDialog(INotAskingPermissionDialog notAskingPermissionDialog) {
        ZPermissions.notAskingPermissionDialog = notAskingPermissionDialog;
    }

    public static INotAskingPermissionDialog getNotAskingPermissionDialog() {
        if(notAskingPermissionDialog==null){
            notAskingPermissionDialog=new NotAskingPermissionDialog();
        }
        return notAskingPermissionDialog;
    }

    /**
     * 权限申请回掉
     *
     * @param mCallback
     */
    public ZPermissions setCallback(Callback mCallback) {
        this.mCallback = mCallback;
        return this;
    }

    public ZPermissions setPermissions(String... permissions) {
        this.permissions = permissions;
        return this;
    }

    /**
     * 权限使用目的描述
     *
     * @param description
     * @return
     */
    public ZPermissions setDescription(String description) {
        this.description = description;
        return this;
    }

    /**
     * 是否在权限申请之前显示权限描述窗口
     *
     * @param showDescription
     * @return
     */
    public ZPermissions setShowDescription(boolean showDescription) {
        this.showDescription = showDescription;
        return this;
    }

    /**
     * 用户拒绝权限后间隔多长时间才能再次请求权限,单位毫秒
     *
     * @param intervalTime <=0表示总是请求,默认0
     * @return
     */
    public ZPermissions setIntervalTime(long intervalTime) {
        this.intervalTime = intervalTime;
        return this;
    }



    /**
     * 用户勾选了不在询问后的提示是否显示
     *
     * @param showNoAsking
     * @return
     */
    public ZPermissions setShowNoAsking(boolean showNoAsking) {
        this.showNoAsking = showNoAsking;
        return this;
    }


    /**
     * 权限申请回掉
     */
    public interface Callback {
        /**
         * @param success 只有全部通过才为true
         * @param granted 存储通过的部分权限
         * @param denied  存储未通过的部分权限
         */
        void onRequestPermissionsResult(boolean success, ArrayList<String> granted, ArrayList<String> denied);
    }


    @Override
    protected void finalize() throws Throwable {
//        Log.i(TAG, "finalize: 销毁PermissionHelper对象");
        unregisterReceiver();
        super.finalize();
    }

    private void unregisterReceiver() {
        try {
            if (mReceiver != null && mContext != null) {
                mContext.unregisterReceiver(mReceiver);
                mReceiver = null;
            }
        } catch (Exception e) {
//            e.printStackTrace();
        }
    }


}
